/* Copyright 2008 Bas van den Berg
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <string>
#include "TrainTask.h"

#include "MudExit.h"
#include "Area.h"
#include "Room.h"
#include "Error.h"
#include "config.h"

using namespace std;
using namespace Chronos;

TrainTask::TrainTask(Area& area_, unsigned int trainRoomID_, MudExit* toTrain)
    : area(area_)
    , trainRoomID(trainRoomID_)
	, currentRoom(0)
    , train(toTrain)
	, currentDest(0)
    , destIter(0)
{}


TrainTask:: ~TrainTask() {
    if (!train->getRoom()) delete train;
    
	while(!destinations.empty()) {
		Destination& dest = destinations.back();
		if (!dest.fromTrain->getRoom()) delete dest.fromTrain;
		destinations.pop_back();
	}
}


void TrainTask::addDestRoom(unsigned int roomID, MudExit* fromTrain) {
	Destination dest(roomID, fromTrain);
    destinations.push_back(dest);
    destIter = destinations.begin();
}


unsigned int TrainTask::run() {
    Room* trainRoom = &area.getRoom(trainRoomID);
    if (destinations.empty()) throw MudError("TrainTask: no destinations");

    if (currentRoom == 0) {
        currentDest = &getNextDest();
        currentRoom = &area.getRoom(currentDest->roomID);
        currentRoom->addObject(train);
        trainRoom->addObject(currentDest->fromTrain);
        string arriveMsg = "The train arrives at the station and the doors open.";
        currentRoom->showText(arriveMsg);
        trainRoom->showText(arriveMsg);
        return seconds(10);
    } else {
        currentRoom->removeObject(train);
        trainRoom->removeObject(currentDest->fromTrain);
        string leaveMsg = "The doors close and the train leaves the station.";
        currentRoom->showText(leaveMsg);
        trainRoom->showText(leaveMsg);
		currentRoom = 0;
        return seconds(20);
    }
}


TrainTask::Destination& TrainTask::getNextDest() {
	Destination& dest = *destIter;
    ++destIter;
    if (destIter == destinations.end()) destIter = destinations.begin();
    return dest;
}

